package com.roads.engineering.controller;

import com.roads.common.annotation.Log;
import com.roads.common.constant.Constants;
import com.roads.common.core.controller.BaseController;
import com.roads.common.core.domain.AjaxResult;
import com.roads.common.core.domain.chart.LineChartModel;
import com.roads.common.core.domain.entity.SysUser;
import com.roads.common.enums.BusinessType;
import com.roads.common.utils.DateUtils;
import com.roads.common.utils.SecurityUtils;
import com.roads.common.utils.StringUtils;
import com.roads.engineering.domain.summary.SummaryIpc;
import com.roads.engineering.domain.summary.SummaryRecord;
import com.roads.engineering.domain.summary.SummaryRecordUserVo;
import com.roads.engineering.domain.summary.SummaryVo;
import com.roads.engineering.service.ISummaryService;
import com.roads.project.domain.ProBoq;
import com.roads.project.domain.ProInstitution;
import com.roads.project.domain.ProPaymentItems;
import com.roads.project.domain.ProPeriod;
import com.roads.project.service.IBidService;
import com.roads.project.service.IProBoqService;
import com.roads.project.service.IProInstitutionService;
import com.roads.project.service.IProPaymentItemsService;
import com.roads.project.service.IProPeriodService;
import com.roads.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName SummaryController
 * @Description 汇总controller
 * @Author nhp
 * @Date 2022/5/5 0005 10:33
 * @Version 1.0.0
 **/
@RestController
@RequestMapping("/engineering/summary")
public class SummaryController extends BaseController {

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IBidService bidService;

    @Autowired
    private IProInstitutionService institutionService;

    @Autowired
    private IProPeriodService periodService;

    @Autowired
    private ISummaryService summaryService;

    @Autowired
    private IProPaymentItemsService paymentItemsService;

    @Autowired
    private IProBoqService boqService;

    @GetMapping("/init")
    public AjaxResult init() {
        AjaxResult ajaxResult = new AjaxResult();
        String userName = getUsername();
        List<ProInstitution> bids = bidService.selectSummaryBidBranch(userName);
        ajaxResult.put("bids", bids);
        if (bids.size() > 0) {
            String institutionCode = bids.get(0).getInstitutionCode();
            ajaxResult.put("institutionCode", institutionCode);
            ProPeriod search = new ProPeriod();
            search.setInstitutionCode(institutionCode);
            List<ProPeriod> periods = periodService.selectModelList(search);
            ajaxResult.put("periods", periods);
            if (periods.size() > 0) {
                //获取当前计量期次
                ProPeriod currentPeriod = periodService.getCurrentPeriod(institutionCode);
                if (StringUtils.isNull(currentPeriod)) {
                    ajaxResult.put("periodName", periods.get(0).getPeriodName());
                } else {
                    ajaxResult.put("periodName", currentPeriod.getPeriodName());
                }
            }
        }
        return ajaxResult;
    }

    /**
     * 汇总前验证登录用户
     *
     * @return 结果
     */
    @GetMapping("/beforeSummaryValidate")
    public AjaxResult beforeSummaryValidate() {
        int count = summaryService.getCountWorkflowNodeUser(getUsername());
        if (count == 0) {
            return error("当前登录用户无法进行汇总操作，请联系管理员");
        }
        return success();
    }

    /**
     * 数据汇总
     *
     * @param model 汇总对象
     * @return 结果
     */
    @PreAuthorize("@ss.hasPermi('engineering:meterage:summary')")
    @Log(title = "工程计量", businessType = BusinessType.SUMMARY)
    @PostMapping("/summary")
    public AjaxResult summary(@RequestBody SummaryVo model) {
        // 验证用户是否可以汇总
        SysUser loginUser = userService.selectUserById(getUserId());
        model.setUserName(loginUser.getUserName());
        model.setCreateByName(loginUser.getNickName());
        model.setSummaryDate(DateUtils.getNowDate());
        System.out.println("标段编号：" + model.getInstitutionCode());
        System.out.println("工期：" + model.getPeriodName());
        System.out.println("是否批复：" + model.getIsApprove());
        // 如果本期已经汇总批复，将无法进行工程计量--如果业主进行解锁汇总则不进行限制
        ProPeriod period = periodService.getPeriodByPeriodName(model.getInstitutionCode(), model.getPeriodName());
        if (Constants.YES.equals(period.getIsLock())) {
            SummaryRecord approveRecord = summaryService.getSummaryRecordByApprove(model.getInstitutionCode(), model.getPeriodName());
            if (StringUtils.isNotNull(approveRecord) && !approveRecord.getCreateBy().equals(model.getUserName())) {
                return AjaxResult.error("本期已批复汇总，无法进行汇总操作");
            }
        }
        // 查看上一期是否最终批复，如果未最终批复，则不能进行本期汇总
        if (!Constants.FIRST_PERIOD.equals(model.getPeriodName())) {
            String lastPeriodName = String.valueOf(Integer.parseInt(model.getPeriodName()) - 1);
            boolean result = summaryService.getSummaryIsApprove(model.getInstitutionCode(), lastPeriodName);
            if (!result) {
                return error("请先批复汇总上一期数据后，才能进行本期数据汇总操作");
            }
        }
        return toAjax(summaryService.summary(model));
    }

    /**
     * 根据机构编号，工期名称，获取汇总用户集合
     *
     * @param institutionCode 机构编号
     * @param periodName 工期
     * @return 结果
     */
    @PostMapping("/dropDownReportUserList")
    public AjaxResult dropDownReportUserList(String institutionCode, String periodName) {
        AjaxResult ajaxResult = new AjaxResult();
        List<SummaryRecordUserVo> list = summaryService.selectSummaryRecordUserList(institutionCode, periodName);
        ajaxResult.put("users", list);
        if (list.size() > 0) {
            //获取当前计量期次
            ajaxResult.put("user", list.get(0).getUser());
        }
        return ajaxResult;
    }

    /**
     * 获取汇总记录是否批复
     *
     * @param institutionCode 机构编号
     * @param periodName 工期
     * @param user 用户
     * @return 结果
     */
    @PostMapping("/getSummaryRecordIsApprove")
    public AjaxResult getSummaryRecordIsApprove(String institutionCode, String periodName, String user) {
        SummaryRecord search = new SummaryRecord();
        search.setInstitutionCode(institutionCode);
        search.setPeriodName(periodName);
        search.setCreateBy(user);
        SummaryRecord summaryRecord = summaryService.getSummaryRecord(search);
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("isApprove", summaryRecord.getIsApprove());
        return ajaxResult;
    }

    /**
     * 根据项目ID获取汇总记录，项目下如果有标段本期未汇总批复，那么批复标识就是true
     *
     * @param projectId 项目ID
     * @param periodName 工期
     * @return 结果
     */
    @PostMapping("/getSummaryRecordIsApproveByProjectId")
    public AjaxResult getSummaryRecordIsApproveByProjectId(Integer projectId, String periodName) {
        AjaxResult ajaxResult = new AjaxResult();
        String isApprove = Constants.YES;
        List<ProInstitution> bids = bidService.selectBidAndBranchByProjectId(projectId);
        for (ProInstitution bid : bids) {
            if (Constants.NO.equalsIgnoreCase(bid.getIsCount())) {
                continue;
            }
            SummaryRecord record = summaryService.getSummaryRecordByApprove(bid.getInstitutionCode(), periodName);
            if (StringUtils.isNull(record)) {
                isApprove = Constants.NO;
                break;
            }
        }
        ajaxResult.put("isApprove", isApprove);
        return ajaxResult;
    }

    /**
     * 获取项目每期百章累计金额--折线图
     *
     * @param projectId 项目ID
     * @return 结果
     */
    @RequestMapping("/getProjectHundredChaptersAccumulateChartLine/{projectId}")
    public AjaxResult getProjectHundredChaptersAccumulateChartLine(@PathVariable("projectId") Integer projectId) {
        AjaxResult ajaxResult = new AjaxResult();
        String userName = SecurityUtils.getUsername();
        boolean isAdmin = SecurityUtils.isAdmin(SecurityUtils.getUserId());
        ProPaymentItems search = new ProPaymentItems();
        search.setProjectId(projectId);
        search.setComputeMode(1);
        List<LineChartModel> lines = new ArrayList<>();
        List<SummaryIpc> ipcs;
        if (isAdmin) {
            ipcs = summaryService.getProjectHundredChaptersCurrentEndTotalByProject(projectId);
        } else {
            ipcs = summaryService.getProjectHundredChaptersCurrentEndTotalByProjectAndUser(projectId, userName);
        }
        List<String> periods = new ArrayList<>();
        List<String> axis = new ArrayList<>();
        String name = "";
        LineChartModel line = null;
        List<Integer> data = null;
        for (SummaryIpc ipc : ipcs) {
            String periodName = "第" + ipc.getPeriodName() + "期";
            if (!periods.contains(periodName)) {
                periods.add(periodName);
            }
            String temp = ipc.getItemCode() + "章";
            if (!axis.contains(temp)) {
                axis.add(temp);
            }
            if (!name.equals(temp)) {
                if (StringUtils.isNotNull(line)) {
                    line.setName(name);
                    line.setData(data);
                    line.setType("line");
                    lines.add(line);
                }
                line = new LineChartModel();
                data = new ArrayList<>();
            }
            name = temp;
            BigDecimal total = ipc.getTotal() == null ? BigDecimal.valueOf(0) : ipc.getTotal();
            total = total.divide(BigDecimal.valueOf(10000),0, BigDecimal.ROUND_HALF_UP);
            Integer value = total.intValue();
            data.add(value);
        }
        if (StringUtils.isNotNull(line)) {
            line.setName(name);
            line.setData(data);
            line.setType("line");
            lines.add(line);
        }
        ajaxResult.put("axis", axis);
        ajaxResult.put("periods", periods);
        ajaxResult.put("lines", lines);
        return ajaxResult;
    }

    /**
     * 获取项目百章合同金额和累计完成金额--柱状图
     *
     * @param projectId 项目ID
     * @return 结果
     */
    @RequestMapping("/getProjectHundredChaptersAccumulateChartBar/{projectId}")
    public AjaxResult getProjectHundredChaptersAccumulateChartBar(@PathVariable("projectId") Integer projectId) {
        AjaxResult ajaxResult = new AjaxResult();
        String userName = SecurityUtils.getUsername();
        boolean isAdmin = SecurityUtils.isAdmin(SecurityUtils.getUserId());
        ProPaymentItems search = new ProPaymentItems();
        search.setProjectId(projectId);
        search.setComputeMode(1);
        List<ProPaymentItems> items = paymentItemsService.selectModelList(search);
        List<SummaryIpc> ipcs;
        if (isAdmin) {
            ipcs = summaryService.getProjectHundredChaptersCurrentEndTotalByProject(projectId);
        } else {
            ipcs = summaryService.getProjectHundredChaptersCurrentEndTotalByProjectAndUser(projectId, userName);
        }
        List<String> axis = new ArrayList<>();
        List<Integer> contractTotal = new ArrayList<>();
        List<Integer> finishTotal = new ArrayList<>();
        for (ProPaymentItems item : items) {
            if ("1".equals(item.getItemStatus())) {
                continue;
            }
            String name = item.getItemCode() + "章";
            if (!axis.contains(name)) {
                axis.add(name);
            }
            // 合同金额
            List<ProInstitution> bids;
            if (isAdmin) {
                bids = institutionService.selectBidListByProjectId(projectId);
            } else {
                bids = institutionService.selectBidListByUserAndProjectId(projectId, userName);
            }
            BigDecimal total = BigDecimal.valueOf(0);
            for (ProInstitution bid : bids) {
                String institutionCode = bid.getInnerCode();
                ProBoq boq = boqService.selectProBoqByCode(institutionCode, item.getItemCode());
                if (StringUtils.isNotNull(boq)) {
                    BigDecimal boqTotal = boq.getTotal() == null ? BigDecimal.valueOf(0) : boq.getTotal();
                    total = total.add(boqTotal);
                }
            }
            total = total.divide(BigDecimal.valueOf(10000),0, BigDecimal.ROUND_HALF_UP);
            contractTotal.add(total.intValue());
            String code = "";
            String period = "";
            BigDecimal wTotal = BigDecimal.valueOf(0);
            for (SummaryIpc ipc : ipcs) {
                if (item.getItemCode().equals(ipc.getItemCode())) {
                    if ("".equals(code)) {
                        code = ipc.getItemCode();
                        period = ipc.getPeriodName();
                        wTotal = ipc.getTotal() == null ? BigDecimal.valueOf(0) : ipc.getTotal();
                    } else {
                        if (code.equals(ipc.getItemCode())) {
                            if (Integer.parseInt(ipc.getPeriodName()) > Integer.parseInt(period)) {
                                period = ipc.getPeriodName();
                                wTotal = ipc.getTotal() == null ? BigDecimal.valueOf(0) : ipc.getTotal();
                            }
                        } else {
                            code = ipc.getItemCode();
                            period = ipc.getPeriodName();
                            wTotal = ipc.getTotal() == null ? BigDecimal.valueOf(0) : ipc.getTotal();
                        }
                    }
                }
            }
            wTotal = wTotal.divide(BigDecimal.valueOf(10000),0, BigDecimal.ROUND_HALF_UP);
            finishTotal.add(wTotal.intValue());
        }
        ajaxResult.put("axis", axis);
        ajaxResult.put("contractTotal", contractTotal);
        ajaxResult.put("finishTotal", finishTotal);
        return ajaxResult;
    }

}
